package com.cxria.shiro.shiro.filter;

import com.cxria.shiro.service.ShiroUserService;
import com.cxria.shiro.dto.ShiroStatus;
import com.cxria.shiro.entity.SUser;
import com.cxria.shiro.enums.ShiroStatusCodeEnum;
import com.cxria.shiro.enums.ShiroStatusMsgEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

public class RequestBodyAuthenticationFilter extends FormAuthenticationFilter {

	private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class);

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired
	private ShiroUserService userService;

	@Override
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		SUser user = getUser(request);
		String username = user.getUsername();
		String password = user.getPassword();
		return createToken(username, password, request, response);
	}

	private SUser getUser(ServletRequest request) {
		SUser user = null;
		try {
			BufferedReader br = request.getReader();
			String line = null;
			StringBuilder bodyStr = new StringBuilder();
			while ((line = br.readLine()) != null) {
				bodyStr.append(line);
			}
			log.info(bodyStr.toString());
			user = objectMapper.readValue(bodyStr.toString(), SUser.class);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return user;
	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		WebUtils.getAndClearSavedRequest(request);
		response.setContentType("application/json;charset=UTF-8");
		String username = (String) SecurityUtils.getSubject().getPrincipal();
		SUser currentUser = userService.getByUsername(username);
		ShiroStatus status = new ShiroStatus(currentUser);
		response.getWriter().append(objectMapper.writeValueAsString(status));
		return false;
	}

	@Override
	protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
		response.setContentType("application/json;charset=UTF-8");
		ShiroStatus status = new ShiroStatus(ShiroStatus.ERROR, ShiroStatusCodeEnum.USER_NOT_LOGIN, ShiroStatusMsgEnum.USER_NOT_LOGIN);
		response.getWriter().append(objectMapper.writeValueAsString(status));
	}

}
